import logging
import copy
from datetime import datetime
from common.mg_core.mg import insert_or_update, MONGODB, get_report_template, get_report
from common.es_core.report_creator import UserReportCreator
from common.es_core.es_interface import es_search_interface
from common.timeutil import get_interval_end_pair
from event_rule.mf_pay.pay_event_rule.user_recharge import USER_RECHARGE_REPORT

_LOGGER = logging.getLogger(__name__)


def get_group_key_list(field, index, start_time, end_time, custom_filter=None):
    filter_list = [{'range': {"_event_time": {"gte": start_time.timestamp(), "lt": end_time.timestamp()}}}]
    if custom_filter:
        filter_list += custom_filter
    dsl = {
        "query": {
            "bool": {
                "filter": filter_list
            }
        },
        "size": 0,
        "aggs": {
            "distinct_user_id": {
                "terms": {
                    "field": field,
                    "size": 100000
                }
            }
        }
    }
    resp_json = es_search_interface(index, dsl)
    buckets = resp_json['aggregations']['distinct_user_id']['buckets']
    mch_list = []
    for bucket in buckets:
        mch_list.append(bucket['key'])
    return mch_list


def get_distinct_mch_id():
    dsl = {"query": {"bool": {"filter": [{"term": {"_event_id": "mch_create"}}]}}}
    resp_json = es_search_interface('mf_pay', dsl)
    return [e['_source']['mch_create_mch_id'] for e in resp_json['hits']['hits']]


def create_mf_pay_info(interval_type, base_time, last_window, event_name, event_rule, index):
    start_time, end_time = get_interval_end_pair(interval_type, base_time, last_window)
    mch_list = get_distinct_mch_id()
    day = str(start_time).split(' ')[0] if interval_type.value == 'day' else str(start_time).split(':')[0]
    result = list()
    for mch in mch_list:
        mch_copy = copy.deepcopy(mch_list)
        mch_copy.remove(mch)
        custom_not_filter = [{"terms": {"_mch_id": mch_copy}}]
        report_id = '-'.join([str(mch), 'all', day, interval_type.value])
        report_template = get_report_template(start_time, interval_type, custom_report_id=report_id)
        report_template.update(dict(mch_id=str(mch), parent_id='all', agency_id='all'))
        result += _create_mf_pay_report(index, start_time, end_time, custom_filter=[],
                                        custom_not_filter=custom_not_filter,
                                        event_rule=event_rule, base_report_template=report_template)
        parent_agency_list = get_group_key_list("_parent_id", index, start_time, end_time, custom_filter=[{"term": {
            "_mch_id": mch}}])
        for parent_id in parent_agency_list:
            custom_filter = [{"term": {"_parent_id": parent_id}}]
            custom_not_filter = [{"terms": {"_mch_id": mch_copy}}]
            report_id = '-'.join([str(mch), str(parent_id), 'all', day, interval_type.value])
            report_template = get_report_template(start_time, interval_type, custom_report_id=report_id)
            report_template.update(dict(mch_id=str(mch), parent_id=str(parent_id), agency_id='all'))
            result += _create_mf_pay_report(index, start_time, end_time, custom_filter=custom_filter,
                                            custom_not_filter=custom_not_filter,
                                            event_rule=event_rule, base_report_template=report_template)
            agency_list = get_group_key_list("_agency_id", index, start_time, end_time,
                                             custom_filter=[{"term": {"_mch_id": mch}},
                                                            {"term": {"_parent_id": parent_id}}])
            for agency_id in agency_list:
                custom_filter = [{"term": {"_parent_id": parent_id}}, {"term": {"_agency_id": agency_id}}]
                custom_not_filter = [{"terms": {"_mch_id": mch_copy}}]
                report_id = '-'.join([str(mch), str(parent_id), str(agency_id), day, interval_type.value])
                report_template = get_report_template(start_time, interval_type, custom_report_id=report_id)
                report_template.update(dict(mch_id=str(mch), parent_id=str(parent_id), agency_id=str(agency_id)))
                result += _create_mf_pay_report(index, start_time, end_time, custom_filter=custom_filter,
                                                custom_not_filter=custom_not_filter,
                                                event_rule=event_rule, base_report_template=report_template)
    MONGODB[index]['mf_pay_financial_report'].remove({'day': day})
    for e in result:
        insert_or_update(e, database=index, collection='mf_pay_financial_report')


def _create_mf_pay_report(index, start_time, end_time, custom_filter, custom_not_filter, event_rule,
                          base_report_template, ):
    mf_report = UserReportCreator.create_user_report(
        start_time=start_time, end_time=end_time, event_rule=event_rule, index=index,
        custom_filter=custom_filter, custom_not_filter=custom_not_filter,
        user_type_as='_first_create_recharged_at', to_group=True
    )
    results = list()
    for report in mf_report['list']:
        report_template = copy.deepcopy(base_report_template)
        mch_type = report['_mch_type']
        report_template['_id'] = '-'.join(['all', report_template['_id'], str(mch_type)])
        report_template.update(report)
        for key in ('agency_recharge_success_count', 'agency_recharge_success_amount'):
            report_template['new_user'][key] = report_template[key]
        report_template['next_day'][key] = report_template[key]
        report_template['veteran_user'][key] = report_template[key]
        report_template['week_user'][key] = report_template[key]
        results.append(report_template)
        # insert_or_update(report_template, database=index, collection=collection)
    return results


def get_agency_stats_report(time_range=None, mch_ids=None, parent_ids=None, agency_ids=None, user_type=None,
                            mch_type=None, sort_by=None, page=None, size=None):
    condition = dict()
    if mch_type:
        condition['_mch_type'] = {"$in": mch_type}
    if mch_ids and ("all" not in mch_ids):
        condition['mch_id'] = {'$in': mch_ids}
    if parent_ids and (
            "all" not in parent_ids or (condition.get('mch_id') or 'all' in mch_ids) and 'all' in agency_ids):
        condition['parent_id'] = {'$in': parent_ids}
    if agency_ids and ("all" not in agency_ids or condition.get('mch_id') or 'all' in mch_ids
                       or condition.get('parent_id')):
        condition['agency_id'] = {'$in': agency_ids}
    condition['day'] = {'$gte': datetime.strftime(time_range[0], "%Y-%m-%d"),
                        '$lte': datetime.strftime(time_range[1], "%Y-%m-%d")}
    (collection, event_rule) = ('mf_pay_financial_report', USER_RECHARGE_REPORT)
    custom_group_by_field = {
        'mch_id': {"$first": "$mch_id"},
        'parent_id': {"$first": "$parent_id"},
        'agency_id': {"$first": "$agency_id"},
        'mch_set': {"$addToSet": "$mch_id"}
    }
    group_key = dict(day="$day")
    custom_value_by_field = dict()
    for key, field in {'mch_ids': 'mch_id', 'parent_ids': 'parent_id', 'agency_ids': 'agency_id'}.items():
        if 'all' not in locals()[key]:
            group_key[field] = '$' + field
        else:
            custom_value_by_field[field] = '-1'
    del_field = ['hour', '_id']
    result, total_count = get_report('mf_pay', collection, condition, sort_key=sort_by, page=page, size=size,
                                     merge_report=True, event_rule=event_rule, group_key=group_key,
                                     custom_group_by_field=custom_group_by_field,
                                     custom_value_by_field=custom_value_by_field,
                                     del_field=del_field, user_type=user_type)
    for e in result:
        e['agency_recharge_success_count'] /= len(e['mch_set'])
        e['agency_recharge_success_amount'] /= len(e['mch_set'])
        e['agency_recharge_success_count'] = round(e['agency_recharge_success_count'])
        e['agency_recharge_success_amount'] = round(e['agency_recharge_success_amount'])
    return result, total_count
